"""
Time                2023/12/27 17:32
Author:             chenshiyan
Email               chenshiyan@linux.alibaba.com
File                ossre_hook.py
Description:
"""
import json,traceback
from apps.task.models import JobModel
from clogger import logger
from .base import HookProcessResult, DiagnosisHookProcessor
from sysom_utils import SysomFramework

ERR_LEVEL = ["normal","warning","error","critical"]

def make_release_ignore_option(instance_ip,key_tmp):
    ret = {}
    try:
        ret = {"key":"ossre_release_ignore-%s"%key_tmp,"label":"解除屏蔽","type": "INVOKE_DIAGNOSIS_HOOK","params":{"type":"release_ignore","instance":instance_ip,"key":key_tmp}}
    except:
        traceback.print_exc()
        pass
    return ret

def flush_data(instance_ip,origin_data):
    try:
        ossre_cache = SysomFramework.gcache("ossre")
        total_abnormal_count = 0
        level_num = {"error":0,"warning":0,"critical":0}
        for i in range(len(origin_data)):
            if True:
                abnormal_count = 0
                inspect_result = "无异常"
                status = "normal"
                if "children" in origin_data[i]:
                    if len(origin_data[i]["children"]) > 0:
                        for k in range(len(origin_data[i]["children"])):
                            abnormal_count_sub1 = 0
                            inspect_result_sub1 = ""
                            status_sub1 = "normal"
                            all_sub1_ignore = 0
                            if ossre_cache.load("%s-%s"%(instance_ip,origin_data[i]["children"][k]["key"])) == 0:
                                all_sub1_ignore = 1
                                release_ignore_ret = make_release_ignore_option(instance_ip,origin_data[i]["children"][k]["key"])
                                for x in range(len(origin_data[i]["children"][k]["options"])):
                                    if origin_data[i]["children"][k]["options"][x]["label"] == "屏蔽检测":
                                        del origin_data[i]["children"][k]["options"][x]
                                        break
                                origin_data[i]["children"][k]["options"].append(release_ignore_ret)

                            if "children" in origin_data[i]["children"][k]:
                                if len(origin_data[i]["children"][k]["children"]) > 0:
                                    for x in range(len(origin_data[i]["children"][k]["children"])):
                                        if ossre_cache.load("%s-%s"%(instance_ip,origin_data[i]["children"][k]["children"][x]["key"])) == 0 or all_sub1_ignore == 1:
                                            origin_data[i]["children"][k]["children"][x]["status"] = "normal"
                                            origin_data[i]["children"][k]["children"][x]["abnormal_count"] = 0
                                            release_ignore_ret = make_release_ignore_option(instance_ip,origin_data[i]["children"][k]["children"][x]["key"])
                                            origin_data[i]["children"][k]["children"][x]["options"].append(release_ignore_ret)
                                            for y in range(len(origin_data[i]["children"][k]["children"][x]["options"])):
                                                if origin_data[i]["children"][k]["children"][x]["options"][y]["label"] == "屏蔽检测":
                                                    del origin_data[i]["children"][k]["children"][x]["options"][y]
                                                    break
                                            if all_sub1_ignore == 1:
                                                for y in range(len(origin_data[i]["children"][k]["children"][x]["options"])):
                                                    if origin_data[i]["children"][k]["children"][x]["options"][y]["label"] == "解除屏蔽":
                                                        del origin_data[i]["children"][k]["children"][x]["options"][y]
                                                        break
                                        else:
                                            if ERR_LEVEL.index(origin_data[i]["children"][k]["children"][x]["status"]) > ERR_LEVEL.index(status_sub1):
                                                status_sub1 = origin_data[i]["children"][k]["children"][x]["status"]
                                            if ERR_LEVEL.index(origin_data[i]["children"][k]["children"][x]["status"]) > ERR_LEVEL.index(status):
                                                status = origin_data[i]["children"][k]["children"][x]["status"]
                                            abnormal_count_sub1 += origin_data[i]["children"][k]["children"][x]["abnormal_count"]
                                            level_num[origin_data[i]["children"][k]["children"][x]["status"]] += 1
                                            if len(inspect_result_sub1) == 0:
                                                inspect_result_sub1 = origin_data[i]["children"][k]["children"][x]["inspect_result"]
                                            else:
                                                inspect_result_sub1 = "%s\n%s"%(inspect_result_sub1,origin_data[i]["children"][k]["children"][x]["inspect_result"])
                            abnormal_count += abnormal_count_sub1
                            if abnormal_count > 0:
                                inspect_result = "存在异常"
                            origin_data[i]["children"][k]["status"] = status_sub1
                            origin_data[i]["children"][k]["abnormal_count"] = abnormal_count_sub1
                            origin_data[i]["children"][k]["inspect_result"] = inspect_result_sub1
                origin_data[i]["status"] = status
                origin_data[i]["abnormal_count"] = abnormal_count
                origin_data[i]["inspect_result"] = inspect_result
                total_abnormal_count += abnormal_count

    except:
        traceback.print_exc()
        pass
    return total_abnormal_count,level_num,origin_data

def flush_checkItems(origin_checkItems,errnum,levelnum):
    try:
        ori_errnum = 0
        ori_warnnum = 0
        ori_critnum = 0
        ori_nornum = 0
        for i in range(len(origin_checkItems)):
            if origin_checkItems[i]["key"] == "告警项":
                ori_warnnum = origin_checkItems[i]["value"]
                origin_checkItems[i]["value"] = levelnum["warning"]
            if origin_checkItems[i]["key"] == "错误项":
                ori_errnum = origin_checkItems[i]["value"]
                origin_checkItems[i]["value"] = levelnum["error"]
            if origin_checkItems[i]["key"] == "严重异常项":
                ori_critnum = origin_checkItems[i]["value"]
                origin_checkItems[i]["value"] = levelnum["critical"]

        for i in range(len(origin_checkItems)):
            if origin_checkItems[i]["key"] == "正常项":
                ori_nornum = origin_checkItems[i]["value"]
                origin_checkItems[i]["value"] = ori_nornum + ori_errnum + ori_warnnum + ori_critnum - levelnum["warning"] - levelnum["error"] - levelnum["critical"]
    except:
        traceback.print_exc()
        pass
    return ori_nornum + ori_errnum + ori_warnnum + ori_critnum, origin_checkItems

def flush_hostInfo(origin_hostInfo,errnum,levelnum,total_count):
    try:
        line_list = origin_hostInfo.replace("\n\n","\n").splitlines()
        del line_list[-1]
        line_list.append("共检测%s项，告警项%s个，错误项%s个，严重异常项%s个"%(total_count,levelnum["warning"],levelnum["error"],levelnum["critical"]))
        origin_hostInfo = "\n\n".join(line_list)
    except:
        traceback.print_exc()
        pass
    return origin_hostInfo

class HookProcessor(DiagnosisHookProcessor):
    async def invoke_hook(self, instance: JobModel, params: dict) -> HookProcessResult:
        ossre_cache = SysomFramework.gcache("ossre")

        op_type = params.get("type", "")
        ossre_key = params.get("key", "")
        instance_ip = params.get("instance", "")
        if op_type == "ignore":
            ossre_cache.store("%s-%s"%(instance_ip,ossre_key),0)
        if op_type == "release_ignore":
            ossre_cache.store("%s-%s"%(instance_ip,ossre_key),1)

        origin_result = json.loads(instance.result)
        try:
            web_data = origin_result["OssreResult"]["data"]
            web_checkItems = origin_result["checkItems"]["data"]
            web_hostInfo = origin_result["hostInfo"]["data"]
            OssreResult_cache = ossre_cache.load("%s-OssreResult"%instance_ip)
            if "data" not in OssreResult_cache:
                origin_data = web_data
            else:
                origin_data = OssreResult_cache["data"]
            if "checkItems" not in OssreResult_cache:
                origin_checkItems = web_checkItems
            else:
                origin_checkItems = OssreResult_cache["checkItems"]
            if "hostInfo" not in OssreResult_cache:
                origin_hostInfo = web_hostInfo
            else:
                origin_hostInfo = OssreResult_cache["hostInfo"]

            total_abnormal_count,level_num,new_data = flush_data(instance_ip,origin_data)
            total_count,new_checkItems = flush_checkItems(origin_checkItems,total_abnormal_count,level_num)
            new_hostInfo = flush_hostInfo(origin_hostInfo,total_abnormal_count,level_num,total_count)

            origin_result["checkItems"]["data"] = new_checkItems
            origin_result["OssreResult"]["data"] = new_data
            origin_result["hostInfo"]["data"] = new_hostInfo
            instance.result = json.dumps(origin_result)
            await self.save_job(instance)

        except:
            traceback.print_exc()
            pass
        
        return HookProcessResult(code=200, data={}, err_msg="")
